home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MACD 5
/
MACD 5.bin
/
workbench
/
time
/
vclock
/
area.c
next >
Wrap
C/C++ Source or Header
|
1994-01-12
|
15KB
|
491 lines
/* $VER: $Id: area.c,v 1.9 1994/01/12 07:47:46 tf Exp $ © 1992,93 by Tobias Ferber */
#include <exec/types.h>
#include <exec/memory.h>
#include <graphics/gfx.h>
#include <graphics/gfxmacros.h>
#include <intuition/intuition.h>
#include <time.h>
#include "timer.h"
/* globals = */
static struct GfxBase *GfxBase;
static struct IntuitionBase *IntuitionBase;
static struct Window *win;
static struct AreaInfo areainfo;
static struct TmpRas tras;
static APTR areabuf= (APTR)NULL;
static PLANEPTR trasbuf= (PLANEPTR)NULL;
static BOOL menuflag= FALSE;
/* the following vd_xxxx are all set by rethink_dimensions() */
static short vd_width, /* current vector digit dimensions */
vd_height,
vd_ypos,
vd_spcx;
#define MAXVECTORS (64*6) /* for the area stuff */
#define AREASIZE ((MAXVECTORS+1) * 5) /* +1 vector for AreaEnd() */
#define TRASSIZE ((win->WScreen->Width/8) * win->WScreen->Height)
static struct NewWindow nw= {
0,0,
350,55,
-1,-1,
CLOSEWINDOW|MENUPICK|NEWSIZE,
GIMMEZEROZERO|SMART_REFRESH,
NULL,NULL,
(UBYTE*)"vClock",
NULL,NULL,
130,20,
-1,-1,
WBENCHSCREEN
};
struct IntuiText quit_text= {
0,1,JAM1,1,1,NULL,"Quit", NULL,
};
struct MenuItem quit_item= {
NULL, 0,0, 0,0, ITEMENABLED|HIGHCOMP|ITEMTEXT|COMMSEQ, 0,
(APTR)&quit_text, NULL, 'Q', NULL, 0
};
struct Menu menu= {
NULL, 0,0, 0,0, MENUENABLED, (BYTE *)"Project", &quit_item, 0,0,0,0
};
#define EDGES 8
struct ptxy { short x,y; } a,b,c,d,e,f,g, /* segment offset */
top[EDGES],
bottom[EDGES],
left[EDGES],
right[EDGES],
mid[4];
/* Init the vector tables of all segments of a vector digit with
* width w and height h. This function will be called when using
* rethink_dimensions().
*/
void init_vectors(short w, short h)
{
unsigned short dx1= (5*w+4)/8,
dx2= (w+1)/2,
dx3= (w+4)/8,
dx4= (w+8)/16,
dy1= (3*h+4)/8,
dy2= (h+2)/4,
dy3= (h+4)/8,
dy4= (h+8)/16;
/* corrections */
dx1= dx4+dx2+dx4;
dy1= dy4+dy2+dy4;
/*
printf("dx1=%d, dx2=%d, dx3=%d, dx4=%d, "
"dy1=%d, dy2=%d, dy3=%d, dy4=%d\n",dx1,dx2,dx3,dx4,
dy1,dy2,dy3,dy4 );
*/
/* segment offsets */
a.x= dx3+dx4; a.y= 0;
b.x= dx3+2*dx4+dx1; b.y= dy4;
c.x= dx3+2*dx4+dx1; c.y= 2*dy4+dy1;
d.x= dx3+2*dx4; d.y= 2*dy1+2*dy4;
e.x= 0; e.y= 2*dy4+dy1;
f.x= 0; f.y= dy4;
g.x= dx3+2*dx4; g.y= dy4+dy1;
/* delta values */
top[0].x= dx1; top[0].y= 0;
top[1].x= 0; top[1].y= dy4;
top[2].x= -dx4; top[2].y= 0;
top[3].x= 0; top[3].y= dy4;
top[4].x= -dx2; top[4].y= 0;
top[5].x= 0; top[5].y= -dy4;
top[6].x= -dx4; top[6].y= 0;
top[7].x= 0; top[7].y= -dy4;
right[0].x= dx3; right[0].y= 0;
right[1].x= 0; right[1].y= dy1;
right[2].x= -dx3; right[2].y= 0;
right[3].x= 0; right[3].y= -dy4;
right[4].x= -dx4; right[4].y= 0;
right[5].x= 0; right[5].y= -dy2;
right[6].x= dx4; right[6].y= 0;
right[7].x= 0; right[7].y= -dy4;
left[0].x= dx3; left[0].y= 0;
left[1].x= 0; left[1].y= dy4;
left[2].x= dx4; left[2].y= 0;
left[3].x= 0; left[3].y= dy2;
left[4].x= -dx4; left[4].y= 0;
left[5].x= 0; left[5].y= dy4;
left[6].x= -dx3; left[6].y= 0;
left[7].x= 0; left[7].y= -dy1;
bottom[0].x= dx2; bottom[0].y= 0;
bottom[1].x= 0; bottom[1].y= dy4;
bottom[2].x= dx4; bottom[2].y= 0;
bottom[3].x= 0; bottom[3].y= dy4;
bottom[4].x= -dx1; bottom[4].y= 0;
bottom[5].x= 0; bottom[5].y= -dy4;
bottom[6].x= dx4; bottom[6].y= 0;
bottom[7].x= 0; bottom[7].y= -dy4;
mid[0].x= dx2; mid[0].y= 0;
mid[1].x= 0; mid[1].y= dy3;
mid[2].x= -dx2; mid[2].y= 0;
mid[3].x= 0; mid[3].y= -dy3;
}
/* rethink the vector digit dimensions for the hh:mm:ss display
* in a rastport of width w and height h and call init_vectors()
*/
void rethink_dimensions(void)
{
short ww= win->Width - win->BorderLeft - win->BorderRight,
wh= win->Height - win->BorderTop - win->BorderBottom;
vd_ypos = (wh + 7) / 13;
vd_spcx = (ww + 16) / 32;
vd_height = wh - (2 * vd_ypos) - 4;
vd_width = (ww - 9 * vd_spcx) / 6;
init_vectors(vd_width, vd_height);
/*
printf("vd_ypos=%d, vd_spcx=%d, vd_height=%d, vd_width=%d\n",
vd_ypos,vd_spcx,vd_height,vd_width);
*/
}
/* Missing in the graphics.library ? */
void AreaPolyDraw(struct RastPort *rp, short x,
short y,
short edges,
short dxy[])
{ short e;
AreaMove(rp,x,y);
for(e=0;e<edges;e++)
{ x+= dxy[2*e];
y+= dxy[2*e+1];
AreaDraw(rp,x,y);
}
}
/* Render a vector digit at (xpos|ypos) into the given RastPort rp.
* Note that this RastPort *MUST* have a fully initialized TmpRas
* and AreaInfo structure.
* If you pass a 'smart' value >=0 to this function, it only
* changes the differing segments between `digit' and `smart'.
* SET segments will be filled with rp's FgPen, UNSET segments
* using the BgPen.
* Passed digit and smart values *MUST* be in [0..15], except
* smart which can be -1 for non-smart rendering.
*/
void render_vecdigit(struct RastPort *rp,short xpos,
short ypos,
int digit,
int smart)
{ static const UBYTE seglist[17][8]= {
/* a b c d e f g */
{ 1,1,1,1,1,1,0 }, /* 0 */
{ 0,1,1,0,0,0,0 }, /* 1 aaaaaaaaaa */
{ 1,1,0,1,1,0,1 }, /* 2 ff aaaaaaaa bb */
{ 1,1,1,1,0,0,1 }, /* 3 fff bbb */
{ 0,1,1,0,0,1,1 }, /* 4 fff bbb */
{ 1,0,1,1,0,1,1 }, /* 5 fff bbb */
{ 1,0,1,1,1,1,1 }, /* 6 ff bb */
{ 1,1,1,0,0,0,0 }, /* 7 gggggggg */
{ 1,1,1,1,1,1,1 }, /* 8 ee gggggggg cc */
{ 1,1,1,1,0,1,1 }, /* 9 eee ccc */
{ 1,1,1,0,1,1,1 }, /* A eee ccc */
{ 0,0,1,1,1,1,1 }, /* B eee ccc */
{ 1,0,0,1,1,1,0 }, /* C ee dddddddd cc */
{ 0,1,1,1,1,0,1 }, /* D dddddddddd */
{ 1,0,0,1,1,1,1 }, /* E */
{ 1,0,0,0,1,1,1 } }; /* F */
if(smart<0)
{ if(seglist[digit][0]) AreaPolyDraw(rp,xpos+a.x,ypos+a.y,EDGES,top);
if(seglist[digit][1]) AreaPolyDraw(rp,xpos+b.x,ypos+b.y,EDGES,right);
if(seglist[digit][2]) AreaPolyDraw(rp,xpos+c.x,ypos+c.y,EDGES,right);
if(seglist[digit][3]) AreaPolyDraw(rp,xpos+d.x,ypos+d.y,EDGES,bottom);
if(seglist[digit][4]) AreaPolyDraw(rp,xpos+e.x,ypos+e.y,EDGES,left);
if(seglist[digit][5]) AreaPolyDraw(rp,xpos+f.x,ypos+f.y,EDGES,left);
if(seglist[digit][6]) AreaPolyDraw(rp,xpos+g.x,ypos+g.y,4,mid);
AreaEnd(rp);
}
else
{ BYTE apen= rp->FgPen;
if(seglist[digit][0] &! seglist[smart][0])
AreaPolyDraw(rp,xpos+a.x,ypos+a.y,EDGES,top);
if(seglist[digit][1] &! seglist[smart][1])
AreaPolyDraw(rp,xpos+b.x,ypos+b.y,EDGES,right);
if(seglist[digit][2] &! seglist[smart][2])
AreaPolyDraw(rp,xpos+c.x,ypos+c.y,EDGES,right);
if(seglist[digit][3] &! seglist[smart][3])
AreaPolyDraw(rp,xpos+d.x,ypos+d.y,EDGES,bottom);
if(seglist[digit][4] &! seglist[smart][4])
AreaPolyDraw(rp,xpos+e.x,ypos+e.y,EDGES,left);
if(seglist[digit][5] &! seglist[smart][5])
AreaPolyDraw(rp,xpos+f.x,ypos+f.y,EDGES,left);
if(seglist[digit][6] &! seglist[smart][6])
AreaPolyDraw(rp,xpos+g.x,ypos+g.y,4,mid);
AreaEnd(rp);
SetAPen(rp,rp->BgPen);
if(seglist[smart][0] &! seglist[digit][0])
AreaPolyDraw(rp,xpos+a.x,ypos+a.y,EDGES,top);
if(seglist[smart][1] &! seglist[digit][1])
AreaPolyDraw(rp,xpos+b.x,ypos+b.y,EDGES,right);
if(seglist[smart][2] &! seglist[digit][2])
AreaPolyDraw(rp,xpos+c.x,ypos+c.y,EDGES,right);
if(seglist[smart][3] &! seglist[digit][3])
AreaPolyDraw(rp,xpos+d.x,ypos+d.y,EDGES,bottom);
if(seglist[smart][4] &! seglist[digit][4])
AreaPolyDraw(rp,xpos+e.x,ypos+e.y,EDGES,left);
if(seglist[smart][5] &! seglist[digit][5])
AreaPolyDraw(rp,xpos+f.x,ypos+f.y,EDGES,left);
if(seglist[smart][6] &! seglist[digit][6])
AreaPolyDraw(rp,xpos+g.x,ypos+g.y,4,mid);
AreaEnd(rp);
SetAPen(rp,apen);
}
}
void set_vclock(struct RastPort *rp, int h, int m, int s, int clr)
{
static int _hh= -1, _h= -1,
_mm= -1, _m= -1,
_ss= -1, _s= -1;
int hh= h/10,
mm= m/10,
ss= s/10;
h%=10;
m%=10;
s%=10;
if(clr) _hh= _h= _mm= _m= _ss= _s= -1;
if(_hh!=hh)
{ render_vecdigit(rp,vd_spcx,vd_ypos,hh,_hh);
_hh=hh;
}
if(_h!=h)
{ render_vecdigit(rp,vd_width+2*vd_spcx,vd_ypos,h,_h);
_h=h;
}
if(_mm!=mm)
{ render_vecdigit(rp,2*vd_width+4*vd_spcx,vd_ypos,mm,_mm);
_mm=mm;
}
if(_m!=m)
{ render_vecdigit(rp,3*vd_width+5*vd_spcx,vd_ypos,m,_m);
_m=m;
}
if(_ss!=ss)
{ render_vecdigit(rp,4*vd_width+7*vd_spcx,vd_ypos,ss,_ss);
_ss=ss;
}
if(_s!=s)
{ render_vecdigit(rp,5*vd_width+8*vd_spcx,vd_ypos,s,_s);
_s=s;
}
}
/* open the system stuff and allocate needed memory */
int open_vectorstuff(void)
{ int ok=0;
if(IntuitionBase=(struct IntuitionBase *)OpenLibrary("intuition.library",0L))
{ struct Screen s; /* for the Workbench Screen data */
if(GetScreenData(&s,sizeof(struct Screen),WBENCHSCREEN,NULL))
{ short hc= s.WBorLeft + s.WBorRight,
vc= s.WBorTop + s.WBorBottom;
if(nw.Title) vc += s.Font->ta_YSize + 1;
nw.Width += hc; nw.MinWidth += hc;
nw.Height += vc; nw.MinHeight += vc;
if(nw.Width < nw.MinWidth) nw.Width = nw.MinWidth;
if(nw.Height < nw.MinHeight) nw.Height = nw.MinHeight;
if(nw.LeftEdge+nw.Width > s.Width)
{ if(nw.Width > s.Width) nw.Width= s.Width;
nw.LeftEdge= s.Width-nw.Width;
}
if(nw.TopEdge+nw.Height > s.Height)
{ if(nw.Height > s.Height) nw.Height= s.Height;
nw.TopEdge= s.Height-nw.Height;
}
}
if(GfxBase=(struct GfxBase *)OpenLibrary("graphics.library",0L))
{ if(win=(struct Window *)OpenWindow(&nw))
{ if(areabuf= (APTR)AllocMem(AREASIZE,MEMF_PUBLIC|MEMF_CLEAR))
{ if(trasbuf= (PLANEPTR)AllocRaster(win->WScreen->Width,
win->WScreen->Height))
{ InitArea(&areainfo,areabuf,MAXVECTORS);
win->RPort->AreaInfo=&areainfo;
win->RPort->TmpRas=(struct TmpRas *)
InitTmpRas(&tras,trasbuf,TRASSIZE);
quit_text.ITextFont= win->WScreen->Font;
quit_item.Height= 2 + win->WScreen->Font->ta_YSize;
quit_item.Width= 4 * IntuiTextLength(&quit_text);
menu.Width= quit_item.Width;
menuflag= SetMenuStrip(win,&menu);
ok= menuflag ? 1:0;
}
else free(areabuf);
}
else CloseWindow(win);
}
else CloseLibrary(GfxBase);
}
else CloseLibrary(IntuitionBase);
}
return ok;
}
void close_vectorstuff(void)
{ if(menuflag && win) ClearMenuStrip(win);
if(trasbuf) FreeRaster(trasbuf,win->WScreen->Width,
win->WScreen->Height);
if(areabuf) FreeMem(areabuf,AREASIZE);
if(win) CloseWindow(win);
if(GfxBase) CloseLibrary(GfxBase);
if(IntuitionBase) CloseLibrary(IntuitionBase);
}
update_titles(struct Window *w, struct tm *lt)
{ static const char *dn[]= { "Sun","Mon","Tue","Wed","Thu","Fri","Sat","Sun" },
*mn[]= { "Jan","Feb","Mar","Apr","May","Jun","Jul","Aug",
"Sep","Oct","Nov","Dec" };
static int d= -1, m= -1, y= -1;
static char wtitle[20];
if(d != lt->tm_mday || m != lt->tm_mon || y != lt->tm_year)
{ d= lt->tm_mday;
m= lt->tm_mon;
y= lt->tm_year;
sprintf(wtitle,"%s %02d-%s-%02d",dn[lt->tm_wday],d,mn[m],y);
SetWindowTitles(w,wtitle,-1L); /* -1 = old title */
}
}
int do_vclock(short leftedge,
short topedge,
short width,
short height,
short setpen,
short unsetpen,
short outline,
short backfill,
short notitle,
long wflags)
{ int rc= -1; /* return code; != 0 indicates failure */
nw.LeftEdge= leftedge;
nw.TopEdge= topedge;
nw.Width= width;
nw.Height= height;
nw.Flags |= wflags;
if(notitle) nw.Title= (UBYTE *)NULL;
if( open_vectorstuff() )
{ struct timerequest *tr= open_timer(NULL,0L);
if(tr != (struct timerequest *)NULL)
{ struct MsgPort *tp= tr->tr_node.io_Message.mn_ReplyPort;
struct RastPort *rp= win->RPort;
BOOL done= FALSE;
rc= 0;
queue_timer(tr,1,0);
rethink_dimensions();
SetAPen(rp,setpen);
SetBPen(rp,unsetpen);
SetOPen(rp,outline);
SetRast(rp,backfill);
/*BNDRYOFF(rp);*/
set_vclock(rp,88,88,88,-1); /* all segments high to init bndry */
while(!done)
{
long timersigmask = (1L << tp->mp_SigBit),
usersigmask = (1L << win->UserPort->mp_SigBit),
breaksigmask = SIGBREAKF_CTRL_C,
sig = Wait(timersigmask | usersigmask | breaksigmask);
done |= (sig & breaksigmask);
if(sig & timersigmask)
{
while(GetMsg(tp) != (struct Message *)NULL)
;
if(CheckIO((struct IORequest *)tr))
{
long t;
struct tm *lt;
time(&t);
lt= (struct tm *)localtime(&t);
set_vclock(rp,lt->tm_hour,lt->tm_min,lt->tm_sec,0);
if(!notitle)
update_titles(win,lt);
queue_timer(tr,1,0);
}
}
if(sig & usersigmask)
{
ULONG class;
UWORD code;
struct IntuiMessage *imsg;
while(imsg= (struct IntuiMessage *)GetMsg(win->UserPort))
{ code= imsg->Code;
done |= ((class= imsg->Class) == CLOSEWINDOW);
ReplyMsg((struct Message *)imsg);
switch(class)
{
case NEWSIZE:
rethink_dimensions();
SetRast(rp,backfill);
set_vclock(rp,88,88,88,-1);
break;
case MENUPICK:
while(code != MENUNULL)
{ struct MenuItem *mi= (struct MenuItem *)ItemAddress(&menu,code);
done |= (MENUNUM(code) == 0 && ITEMNUM(code) == 0);
code= (mi && mi->NextSelect != code) ? mi->NextSelect : MENUNULL;
}
break;
}
}
}
}
purge_timer(tr);
close_timer(tr);
}
close_vectorstuff();
}
return rc;
}